# -*- coding:utf-8 -*-
import numpy as np
from algorithms.train import Trainable

class Linear(Trainable):

	def __init__(self,w=None):
		if w is not None:
			self.w=w
		else:
			self.w=None 

	def fit1(self,data,label):
		print("the data shape is samples : {0[0]}, feature size :{0[1]}".format(data.shape))
		bone=np.ones(data.shape[0]).reshape(data.shape[0],1)
		self.X=np.mat(np.hstack((data,bone)))
		self.y=np.mat(label.reshape(data.shape[0],1))
		shape=self.X.shape
		self.w=np.linalg.pinv(self.X)*self.y
		print("the weights shape is {0}".format(self.w.shape[0]))

	def fit0(self,data,label):
		bone=np.ones(data.shape[0]).reshape(data.shape[0],1)
		self.X=np.mat(np.hstack((data,bone)))
		self.y=np.mat(label.reshape(data.shape[0],1))
		shape=self.X.shape
		item_size=shape[0]
		feature_size=shape[1]
		self.w=np.mat(np.ones((feature_size,1)))
		times=2000
		alpha=0.02
		for i in range(1000):
			hx=np.dot(self.X,self.w)
			diff=hx-self.y
			error=alpha*(1.0/item_size)*np.dot(self.X.T,diff)
			w_new=self.w-error
			self.w=w_new

	def predict(self,data):
		feature_size=data.size
		current=np.mat(np.hstack((data.reshape(1,feature_size),np.ones(1).reshape(1,1))))*self.w
		return current